package trinnes.oliver.unimaas.smartpentalath.control;

import java.awt.Window;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javax.swing.JOptionPane;
import trinnes.oliver.unimaas.smartpentalath.data.Move;

/**
 *
 * @author Oliver Trinnes
 */
public class GameController implements PropertyChangeListener
{
  private Game game;
  private String publishedStatus;
  private boolean noMovesLeft1;
  private PropertyChangeSupport propertyChangeSupport;

  public GameController(Game game)
  {
    this.game = game;
    propertyChangeSupport = new PropertyChangeSupport(this);
    game.getPlayer1().addPropertyChangeListener(this);
    game.getPlayer2().addPropertyChangeListener(this);
  }

  public void undoLastMove()
  {
    game.getCurrentPlayer().setNextMove(Move.UNDO);
  }

  public String getStatus()
  {
    return publishedStatus;
  }

  public void start()
  {
    while(!game.isGameOver())
    {
      // Set current player
      if(game.getCurrentPlayer() == null)
        game.setCurrentPlayer(game.getPlayer1());
      else
        game.switchPlayer();

      // Are there still moves left for current player?
      game.setMovesLeft(
          game.getPossibleMovesNumber(game.getCurrentPlayer().getPiece()));
      if(game.getMovesLeft() == 0)
      {
        if(noMovesLeft1)
          break;

        noMovesLeft1 = true;
        JOptionPane.showMessageDialog(Window.getWindows()[0], "There are no moves left for "
            + game.getCurrentPlayer().getName() + ". He passes.",
            "No moves left",
            JOptionPane.INFORMATION_MESSAGE);
      }
      else
      {
        noMovesLeft1 = false;
        // Wait for next move
        if(game.getCurrentPlayer() instanceof HumanPlayer)
          setStatus("Please select next move, " + game.getCurrentPlayer() + ".");
        else
          setStatus("Waiting for " + game.getCurrentPlayer() + "...");
        int move = game.getCurrentPlayer().getNextMove();

        // Execute selected move
        game.doAction(move, game.getCurrentPlayer());
        propertyChangeSupport.firePropertyChange("new_move", Move.NO_MOVE, move);
      }
    }
    game.setCurrentPlayer(null);
    String gameOverInfo = "";
    if(game.getWinner() == null)
      gameOverInfo += "Game over! The game is a draw or was interrupted.";
    else
      gameOverInfo += "Game over! Winner: " + game.getWinner();
    setStatus(gameOverInfo);
    JOptionPane.showMessageDialog(Window.getWindows()[0], gameOverInfo, "Game Over",
        JOptionPane.INFORMATION_MESSAGE);
  }

  public void setStatus(String status)
  {
    String oldStatus = this.publishedStatus;
    this.publishedStatus = status;
    propertyChangeSupport.firePropertyChange("status_update", oldStatus, status);
  }

  public void addPropertyChangeListener(PropertyChangeListener listener)
  {
    propertyChangeSupport.addPropertyChangeListener(listener);
  }

  public void removePropertyChangeListener(PropertyChangeListener listener)
  {
    propertyChangeSupport.removePropertyChangeListener(listener);
  }

  public void propertyChange(PropertyChangeEvent evt)
  {
    if(evt.getPropertyName().equals("new_progress"))
      setStatus("Waiting for " + game.getCurrentPlayer() + ": " + evt.
          getNewValue() + " sec...");
  }

}
